Use case: DCMI continuous capture with decimation

Capture continuous frames using decimation. The application is notified per frame via a callback.

Sequence diagram

Continuous capture using HAL1 DCMI + DMA APIs.

  @startuml
  hide footbox
  participant "User Application" as app
  participant "DCMI Driver" as dcmi
  participant "DMA Driver" as dma

  group Initialization + configuration
     app->dcmi : HAL_DCMI_Init()
     dcmi-->app : HAL_OK
     app->dcmi : __HAL_LINKDMA()
     note right: link DMA handle to DCMI handle
  end

  group Process (continuous frames)
     app->dcmi : HAL_DCMI_Start_DMA()
     dcmi-->app : HAL_OK
     group Repeat per frame
        dma->dcmi : DMA transfer complete
        dcmi-->app : HAL_DCMI_FrameEventCallback()
     end
  end

  group De-initialization
     app->dcmi : HAL_DCMI_DeInit()
     dcmi-->app : HAL_OK
  end
  @enduml

Code snippet

HAL1

HAL2

DCMI_HandleTypeDef hdcmi;
DMA_HandleTypeDef hdma;


uint32_t *buf = (uint32_t*)0x24000000U;
uint32_t words = 640U * 480U * 2U / 4U;

hdcmi.Instance              = DCMI;


hdcmi.Init.JPEGMode         = DCMI_JPEG_DISABLE;
hdcmi.Init.PCKPolarity      = DCMI_PCKPOLARITY_FALLING;
hdcmi.Init.HSPolarity       = DCMI_HSPOLARITY_HIGH;
hdcmi.Init.VSPolarity       = DCMI_VSPOLARITY_HIGH;
hdcmi.Init.ExtendedDataMode = DCMI_EXTEND_DATA_8B;


hdcmi.Init.SynchroMode      = DCMI_SYNCHRO_HARDWARE;



hdcmi.Init.CaptureRate      = DCMI_CR_ALL_FRAME;


hdcmi.Init.ByteSelectMode   = DCMI_BSM_ALTERNATE_2;
hdcmi.Init.ByteSelectStart  = DCMI_OEBS_ODD;
hdcmi.Init.LineSelectMode   = DCMI_LSM_ALTERNATE_2;
hdcmi.Init.LineSelectStart  = DCMI_OELS_EVEN;
HAL_DCMI_Init(&hdcmi);
__HAL_LINKDMA(&hdcmi, DMA_Handle, hdma);

HAL_DCMI_Start_DMA(&hdcmi, DCMI_MODE_CONTINUOUS, buf, words);

void HAL_DCMI_FrameEventCallback(DCMI_HandleTypeDef *hdcmi)
{
}
HAL_DCMI_DeInit(&hdcmi);
 hal_dcmi_handle_t hdcmi;
 hal_dma_handle_t hdma;
 hal_dcmi_parallel_config_t parallel_cfg;
 hal_dcmi_pipe_config_t pipe_cfg;
 uint32_t *buf = (uint32_t*)0x24000000U;
 uint32_t len = 640U * 480U * 2U;

 HAL_DCMI_Init(&hdcmi, HAL_DCMI);
 HAL_DCMI_SetDMA(&hdcmi, &hdma);

 parallel_cfg.format = HAL_DCMI_FORMAT_UNCOMPRESSED;
 parallel_cfg.pixel_polarity = HAL_DCMI_PIXEL_CLOCK_FALLING;
 parallel_cfg.hsync_polarity = HAL_DCMI_HSYNC_HIGH;
 parallel_cfg.vsync_polarity = HAL_DCMI_VSYNC_HIGH;
 parallel_cfg.data_width = HAL_DCMI_EXTENDED_DATA_8_BITS;
 HAL_DCMI_PARALLEL_SetConfig(&hdcmi, &parallel_cfg);

/* Synchro mode is set to HARDWARE by default */



 pipe_cfg.frame_rate = HAL_DCMI_FRAME_CAPTURE_ALL;
 HAL_DCMI_SetConfigPipe(&hdcmi, HAL_DCMI_PIPE_0, &pipe_cfg);

 HAL_DCMI_SetPipeBytesDecimation(&hdcmi, HAL_DCMI_PIPE_0,
                                  HAL_DCMI_BYTE_CAPTURE_2BYTE_OUT_4_ODD);
 HAL_DCMI_SetPipeLinesDecimation(&hdcmi, HAL_DCMI_PIPE_0,
                                  HAL_DCMI_LINE_CAPTURE_1LINE_OUT_2_EVEN);



 HAL_DCMI_StartPipe_DMA(&hdcmi, HAL_DCMI_PIPE_0, HAL_DCMI_CAPTURE_CONTINUOUS, buf, len);

 void HAL_DCMI_PipeFrameEventCallback(hal_dcmi_handle_t *hdcmi, hal_dcmi_pipe_t pipe)
 {
 }
 HAL_DCMI_DeInit(&hdcmi);

Key changes

  1. HAL2 configures decimation through HAL_DCMI_SetPipeBytesDecimation() and HAL_DCMI_SetPipeLinesDecimation().

  2. HAL2 performs capture through a pipe using HAL_DCMI_StartPipe_DMA().

  3. Frame notifications are pipe-specific through HAL_DCMI_PipeFrameEventCallback().